/**
 * 防抖
 *
 * @param {Function} func 回调函数
 * @param {Number} wait 延时
 * @param {Boolean} immediate 立即执行
 * @return {Function}
 */
export function debounce(func: any, wait = 500, immediate = false) {
  let timeout: any = null
  return function (...args: any[]) {
    if (timeout !== null) clearTimeout(timeout)
    if (immediate) {
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow) typeof func === 'function' && func.apply(this, args)
    } else {
      timeout = setTimeout(() => {
        typeof func === 'function' && func.apply(this, args)
      }, wait)
    }
  }
}

/**
 * 监听窗口变化
 */
export class Resize {
  static instance: any  = null

  static cacheEvent = new Set()
  _handler: any
  constructor() {
    if (Resize.instance) {
      return Resize.instance
    }
    this._handler = debounce(this.handler, 200)
    this.listen()
    Resize.instance = this
  }

  listen() {
    if (Resize.instance) return
    window.addEventListener('resize', this._handler)
  }

  unListen() {
    Resize.cacheEvent.clear()
    Resize.instance = null
    window.removeEventListener('resize', this._handler)
  }

  /**
   * resize回调函数
   * @param {EventListener} e resize回调函数携带的参数
   */
  handler() {
    for (const event of Resize.cacheEvent) {
      typeof event === 'function' && event()
    }
  }

  /**
   * 监听回调所执行的方法
   * @param {Function} event
   */
  on(event) {
    Resize.cacheEvent.add(event)
  }

  /**
   * 移除回调方法
   * @param {Function} event
   */
  remove(event) {
    Resize.cacheEvent.delete(event)
    if (!Resize.cacheEvent.size) {
      this.unListen()
    }
  }
}
